/**
 * 字体类 通过【GLFontBitmap】生成字体位图 然后通过【GLTexContainer】生成纹理
 * @date   2011-3-27
 * @author tianye
 */
package cn.edu.dlut.WingGame.Graphic;

import java.nio.FloatBuffer;
import java.util.Hashtable;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Typeface;
import cn.edu.dlut.WingGame.BaseType.WingColor;

public class GLFont {
	public Typeface mTypeface;
	public int fontSize;
	public WingColor fontColor;

	public int charHeight;// 字符高度

	public boolean isEnUsed = false;
	public int enCharCount = 0;
	public int bmpWidth;
	public int bmpHeight;
	public Bitmap enbitmap = null;

	public boolean isCnUsed = false;
	public int cnCharCount = 0;
	public int cnX = 0;
	public int cnY = 0;
	public int cnMax = 0;
	public float cnDescent = 0;
	public Bitmap cnbitmap = Bitmap.createBitmap(512, 512,
			Bitmap.Config.ARGB_8888);// 固定512*512大小
	// Map用 put(k,v) /
	// get(k)，还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。
	// Hashtable继承Map接口，实现一个key-value映射的哈希表。

	public Hashtable<Character, GLFontChar> enCharTable = new Hashtable<Character, GLFontChar>();
	public Hashtable<Character, GLFontChar> cnCharTable = new Hashtable<Character, GLFontChar>();

	private GLTexData enTexdata = new GLTexData();
	private GLTexData cnTexdata = new GLTexData();

	public void creatFont(int fontsize, WingColor fontcolor) {

		mTypeface = Typeface.DEFAULT;
		this.fontSize = fontsize;
		this.fontColor = fontcolor;
		GLFontBitmap.creatFontBitmapEn(this);

	}

	public void creatFont(String fontname, int fontsize, WingColor fontcolor,
			boolean isbold, boolean isitalic) {
		int style;
		if (isbold && isitalic)
			style = Typeface.BOLD_ITALIC;
		else if (isbold)
			style = Typeface.BOLD;
		else if (isitalic)
			style = Typeface.ITALIC;
		else
			style = Typeface.NORMAL;
		mTypeface = Typeface.create(fontname, style);
		this.fontSize = fontsize;
		this.fontColor = fontcolor;
		GLFontBitmap.creatFontBitmapEn(this);
	}

	public void creatFont(Typeface typeface, int fontsize, WingColor fontcolor) {

		this.fontSize = fontsize;
		this.fontColor = fontcolor;
		mTypeface = typeface;
		GLFontBitmap.creatFontBitmapEn(this);
	}

	public void creatFont(String ttfPath, int fontsize, WingColor fontcolor) {

		this.fontSize = fontsize;
		this.fontColor = fontcolor;
		mTypeface = Typeface.createFromAsset(
				GLDevice.getActivity().getAssets(), ttfPath);
		GLFontBitmap.creatFontBitmapEn(this);
	}

	public float getCharWidth(char c) {
		GLFontChar tmp;
		if (checkEnChar(c))
			tmp = enCharTable.get(c);
		else
			tmp = cnCharTable.get(c);
		return tmp.charWidth;
	}

	public float getCharHeight(char c) {
		return charHeight - 4;
	}

	public void checkBind()// 检查是否生成纹理并第一次绑定
	{
		if (enTexdata.isBind)
			return;
		try {
			GLTexContainer.creatTexture(enbitmap, enTexdata);
			enTexdata.isBind = true;
			enbitmap.recycle();
			enbitmap = null;
		} catch (Exception e) {
			enTexdata.isBind = false;
		}

	}

	public void checkBindEx()// 检查是否生成纹理并第一次绑定
	{
		if (cnTexdata.isBind)
			return;
		try {
			if (cnTexdata.mTextureID != -1)
				GLTexContainer.deleteTexture(cnTexdata.mTextureID);
			GLTexContainer.creatTexture(cnbitmap, cnTexdata);
			cnTexdata.isBind = true;
		} catch (Exception e) {
			cnTexdata.isBind = false;
		}

	}

	public boolean checkEnChar(char c) {
		if ((c) < 128)
			return true;
		else {
			if (!cnCharTable.containsKey(c)) {
				GLFontBitmap.creatFontBitmapCn(this, c);
				cnTexdata.isBind = false;
			}
		}
		return false;
	}

	private void drawChar(float x, float y, GLFontChar tmp) {
		if (!enTexdata.isBind) {
			checkBind();
			return;
		}

		GLDevice.enableBlend();

		GLDevice.getGL().glEnable(GL10.GL_TEXTURE_2D);
		GLDevice.getGL().glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		GLDevice.getGL().glEnableClientState(GL10.GL_VERTEX_ARRAY);
		GLDevice.getGL().glColor4f(1.0f, 1.0f, 1.0f, GLDevice.getAlpha());
		// 绑定
		GLDevice.getGL()
				.glBindTexture(GL10.GL_TEXTURE_2D, enTexdata.mTextureID);

		// 映射
		FloatBuffer verticleBuffer = FloatBuffer.wrap(new float[] { x, y,
				x + charHeight, y, x, y + charHeight, x + charHeight,
				y + charHeight, });

		GLDevice.getGL()
				.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tmp.coordBuffer);
		GLDevice.getGL().glVertexPointer(2, GL10.GL_FLOAT, 0, verticleBuffer);
		GLDevice.getGL().glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

		GLDevice.getGL().glDisableClientState(GL10.GL_VERTEX_ARRAY);
		GLDevice.getGL().glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		GLDevice.getGL().glDisable(GL10.GL_TEXTURE_2D);

		GLDevice.disableBlend();
	}

	private void drawCharEx(float x, float y, GLFontChar tmp) {
		if (!cnTexdata.isBind) {
			checkBindEx();
		}

		GLDevice.enableBlend();

		GLDevice.getGL().glEnable(GL10.GL_TEXTURE_2D);
		GLDevice.getGL().glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		GLDevice.getGL().glEnableClientState(GL10.GL_VERTEX_ARRAY);

		// 绑定
		GLDevice.getGL()
				.glBindTexture(GL10.GL_TEXTURE_2D, cnTexdata.mTextureID);

		// 映射
		FloatBuffer verticleBuffer = FloatBuffer.wrap(new float[] { x, y,
				x + charHeight, y, x, y + charHeight, x + charHeight,
				y + charHeight, });

		GLDevice.getGL()
				.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tmp.coordBuffer);
		GLDevice.getGL().glVertexPointer(2, GL10.GL_FLOAT, 0, verticleBuffer);
		GLDevice.getGL().glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

		GLDevice.getGL().glDisableClientState(GL10.GL_VERTEX_ARRAY);
		GLDevice.getGL().glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		GLDevice.getGL().glDisable(GL10.GL_TEXTURE_2D);

		GLDevice.disableBlend();

	}

	public void drawChar(float x, float y, char c) {
		if (checkEnChar(c)) {
			GLFontChar tmp = enCharTable.get(c);
			drawChar(x, y, tmp);
		} else {
			GLFontChar tmp = cnCharTable.get(c);
			drawCharEx(x, y, tmp);
		}
	}

	public void drawText(float x, float y, String str) {
		GLDevice.getGL().glColor4f(1, 1, 1, 1);
		float w;
		for (int i = 0; i < str.length(); i++) {
			w = getCharWidth(str.charAt(i));
			drawChar(x, y, str.charAt(i));
			x = x + w;
		}

	}

	public void drawText(Rect rect, String str) {
		GLDevice.getGL().glColor4f(1, 1, 1, 1);
		int x = rect.left;
		int y = rect.top + charHeight - 4;
		float w;
		for (int i = 0; i < str.length(); i++) {
			w = getCharWidth(str.charAt(i));
			if (x + w > rect.right) {
				x = rect.left;
				y = y + (charHeight - 4);
			}
			drawChar(x, y, str.charAt(i));
			x = (int) (x + w);
		}

	}
	// public void test(){
	// if(!cnTexdata.isBind)
	// {
	// checkBindEx();
	// }
	//	
	// GLDevice.enbleBlend();
	//    	
	// GLDevice.getGL().glEnable(GL10.GL_TEXTURE_2D);
	// GLDevice.getGL().glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	// GLDevice.getGL().glEnableClientState(GL10.GL_VERTEX_ARRAY);
	//        
	// // 绑定
	// GLDevice.getGL().glBindTexture(GL10.GL_TEXTURE_2D, cnTexdata.mTextureID);
	//
	// // 映射
	// FloatBuffer verticleBuffer = FloatBuffer.wrap(new float[]{
	// 0,0,
	// 320, 0,
	// 0, 320,
	// 320, 320,
	// });
	// FloatBuffer coordBuffer = FloatBuffer.wrap(new float[]{
	// 0,0,
	// 1,0,
	// 0,1,
	// 1,1,
	// });
	// GLDevice.getGL().glTexCoordPointer(2, GL10.GL_FLOAT, 0, coordBuffer);
	// GLDevice.getGL().glVertexPointer(2, GL10.GL_FLOAT, 0, verticleBuffer);
	// GLDevice.getGL().glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
	//        
	// GLDevice.getGL().glDisableClientState(GL10.GL_VERTEX_ARRAY);
	// GLDevice.getGL().glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	// GLDevice.getGL().glDisable(GL10.GL_TEXTURE_2D);
	//        
	// GLDevice.disableBlend();
	//		
	// }

}

/**
 * @author tianye 描述一个字符在纹理中的位置
 */
class GLFontChar {
	public int charWidth;// 字符宽度
	FloatBuffer coordBuffer;
}
